Package weasel.interpreter

Source Code of weasel.interpreter.WeaselThread$StackElement

package weasel.interpreter;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import weasel.interpreter.bytecode.WeaselInstruction;
import weasel.interpreter.bytecode.WeaselInstructionNoTime;


public final class WeaselThread implements WeaselSaveable {
 
  protected final WeaselInterpreter interpreter;
  protected final String name;
  protected final StackElement stack[];
  protected int stackPointer;
  protected WeaselMethodExecutor methodExecutor;
  protected long sleepTime=0;
  protected long lastRunTime;
  protected boolean waiting;
  protected int exception;
 
  protected WeaselThread(WeaselInterpreter interpreter, String name, int stackSize){
    this.interpreter = interpreter;
    this.name = name;
    stack = new StackElement[stackSize];
    lastRunTime = System.currentTimeMillis();
  }
 
  public WeaselThread(WeaselInterpreter interpreter, DataInputStream dataInputStream) throws IOException {
    this.interpreter = interpreter;
    name = dataInputStream.readUTF();
    int stackSize = dataInputStream.readInt();
    stack = new StackElement[stackSize];
    stackPointer = dataInputStream.readInt();
    for(int i=0; i<stackPointer; i++){
      stack[i] = new StackElement(dataInputStream);
    }
    if(dataInputStream.readBoolean()){
      methodExecutor = new WeaselMethodExecutor(this, dataInputStream);
    }
    sleepTime = dataInputStream.readLong();
    lastRunTime = System.currentTimeMillis();
    waiting = dataInputStream.readBoolean();
    exception = dataInputStream.readInt();
  }

  @Override
  public void saveToDataStream(DataOutputStream dataOutputStream) throws IOException{
    dataOutputStream.writeUTF(name);
    dataOutputStream.writeInt(stack.length);
    dataOutputStream.writeInt(stackPointer);
    for(int i=0; i<stackPointer; i++){
      stack[i].saveToDataStream(dataOutputStream);
    }
    dataOutputStream.writeBoolean(methodExecutor!=null);
    if(methodExecutor!=null){
      methodExecutor.saveToDataStream(dataOutputStream);
    }
    dataOutputStream.writeLong(sleepTime);
    dataOutputStream.writeBoolean(waiting);
    dataOutputStream.writeInt(exception);
  }
 
  public State getThreadState() {
    if(methodExecutor==null)
      return State.TERMINATED;
    if(sleepTime>0)
      return State.SLEEPING;
    if(waiting)
      return State.WAITING;
    return State.RUNNING;
  }

  public void sleepUpdate(){
    long currentTime = System.currentTimeMillis();
    sleepTime -= currentTime-lastRunTime;
    lastRunTime = currentTime;
    if(sleepTime<=0)
      sleepTime = 0;
  }
 
  public void runNextInstruction() {
    WeaselInstruction instrucion;
    do{
      while(true){
        instrucion = methodExecutor.getNextInstruction();
        if(instrucion!=null)
          break;
        callReturn();
        if(methodExecutor==null)
          return;
      }
      try{
        instrucion.run(interpreter, this, methodExecutor);
      }catch(Throwable e){
        WeaselRuntimeException wre;
        if(e instanceof WeaselRuntimeException){
          wre = (WeaselRuntimeException)e;
        }else{
          wre = new WeaselRuntimeException(e, this);
        }
        setException(interpreter.baseTypes.createException("OVMException;", wre.getMessage(), 0));
      }
      if(methodExecutor==null)
        return;
      if(exception!=0){
        while(true){
          boolean anyCatch = methodExecutor.gotoCatchForClass(interpreter.getObject(exception).getWeaselClass());
          if(anyCatch)
            break;
          callReturn();
          if(methodExecutor==null)
            return;
        }
      }
    }while(instrucion instanceof WeaselInstructionNoTime);
  }
 
  public void setWaiting(boolean waiting) {
    this.waiting = waiting;
  }

  @Override
  public String toString() {
    return "Thread-"+name;
  }

  public void sleep(long toSleep) {
    sleepTime = toSleep;
  }
 
  public void call(WeaselMethodBody methodBody){
    methodExecutor = new WeaselMethodExecutor(this, methodBody, methodExecutor);
  }
 
  public void callReturn(){
    methodExecutor = methodExecutor.getCaller();
  }
 
  public StackTraceElement[] getStackTrace(){
    return methodExecutor.getStackTrace().toArray(new StackTraceElement[0]);
  }
 
  public void setException(int exception){
    this.exception = exception;
  }
 
  public int getException() {
    return exception;
  }

  public String getName() {
    return name;
  }

  public StackElement pop(){
    if(stackPointer==0){
      throw new WeaselNativeException("Stack underflow");
    }
    StackElement se = stack[--stackPointer];
    stack[stackPointer] = null;
    return se;
  }
 
  public Object popValue(){
    return pop().value;
  }
 
  public int popObject(){
    return pop().object;
  }
 
  public void push(StackElement value){
    if(stackPointer==stack.length){
      throw new WeaselNativeException("Stack overflow");
    }
    stack[stackPointer++] = value;
  }
 
  public void pushValue(Object value){
    push(new StackElement(value));
  }
 
  public void pushObject(int value){
    push(new StackElement(value));
  }
 
  public StackElement get(int pos){
    if(pos<0||pos>=stackPointer)
      throw new WeaselNativeException("Stack out of bounds %s %s", pos, stackPointer);
    StackElement se = stack[pos];
    return se;
  }
 
  public Object getValue(int pos){
    return get(pos).value;
  }
 
  public int getObject(int pos){
    return get(pos).object;
  }
 
  public void set(int pos, StackElement se){
    if(pos<0||pos>=stackPointer)
      throw new WeaselNativeException("Stack out of bounds %s %s", pos, stackPointer);
    stack[pos] = se;
  }
 
  public void setValue(int pos, Object value){
    get(pos).value = value;
  }
 
  public void setObject(int pos, int value){
    get(pos).object = value;
  }
 
  public int getStackPointer(){
    return stackPointer;
  }
 
  public void setStackPointer(int stackPointer){
    this.stackPointer = stackPointer;
  }
 
  public void markKnownObjects() {
    for(int i=0; i<stackPointer; i++){
      if(stack[i].value==null){
        interpreter.getObject(stack[i].object).markVisible();
      }
    }
    if(exception!=0){
      interpreter.getObject(exception).markVisible();
    }
  }
 
  public static enum State{
    RUNNING,
    WAITING,
    TERMINATED,
    SLEEPING
  }
 
  public static class StackElement implements WeaselSaveable{
    public Object value;
    public int object;
   
    public StackElement(Object value) {
      this.value = value;
    }
   
    public StackElement(int object) {
      this.object = object;
    }

    public StackElement(DataInputStream dataInputStream) throws IOException {
      int t = dataInputStream.readInt();
      switch(t){
      case 1:
        object = dataInputStream.readInt();
        break;
      case 2:
        value = dataInputStream.readBoolean();
        break;
      case 3:
        value = dataInputStream.readChar();
        break;
      case 4:
        value = dataInputStream.readByte();
        break;
      case 5:
        value = dataInputStream.readShort();
        break;
      case 6:
        value = dataInputStream.readInt();
        break;
      case 7:
        value = dataInputStream.readLong();
        break;
      case 8:
        value = dataInputStream.readFloat();
        break;
      case 9:
        value = dataInputStream.readDouble();
        break;
      }
    }
   
    @Override
    public void saveToDataStream(DataOutputStream dataOutputStream) throws IOException {
      if(value==null){
        dataOutputStream.writeInt(1);
        dataOutputStream.writeInt(object);
      }else{
        Class<?> c = value.getClass();
        if(c==Boolean.class){
          dataOutputStream.writeInt(2);
          dataOutputStream.writeBoolean((Boolean)value);
        }else if(c==Character.class){
          dataOutputStream.writeInt(3);
          dataOutputStream.writeChar((Character)value);
        }else if(c==Byte.class){
          dataOutputStream.writeInt(4);
          dataOutputStream.writeByte((Byte)value);
        }else if(c==Short.class){
          dataOutputStream.writeInt(5);
          dataOutputStream.writeShort((Short)value);
        }else if(c==Integer.class){
          dataOutputStream.writeInt(6);
          dataOutputStream.writeInt((Integer)value);
        }else if(c==Long.class){
          dataOutputStream.writeInt(7);
          dataOutputStream.writeLong((Long)value);
        }else if(c==Float.class){
          dataOutputStream.writeInt(8);
          dataOutputStream.writeFloat((Float)value);
        }else if(c==Double.class){
          dataOutputStream.writeInt(9);
          dataOutputStream.writeDouble((Double)value);
        }
      }
    }
  }
 
}
TOP

Related Classes of weasel.interpreter.WeaselThread$StackElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.